/*
 * Copyright 2012-2013 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgettable.client.ui.grid.cell.link;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.safehtml.shared.UriUtils;
import com.google.gwt.user.client.Window;

import finbudget.shared.process.events.StringPair;
import finbudgettable.client.ui.grid.cell.HasMultilineStyle;

public class LinkCell extends AbstractCell<StringPair> implements HasMultilineStyle {

	public interface Template extends SafeHtmlTemplates {
		@Template("<div class=\"{0}\">{1}</div>")
		SafeHtml div(String className, SafeHtml text);

		@Template("<a class=\"link\" href=\"{0}\">{1}</a>")
		SafeHtml link(SafeUri url, String content);
	}

	public interface Resources extends ClientBundle {

		interface Style extends CssResource {
			@ClassName("b-link-cell__multiline_text")
			String bLinkCell__multiline_text();

			@ClassName("b-link-cell")
			String bLinkCell();

			@ClassName("b-link-cell__text")
			String bLinkCell__text();
		}

		@Source("LinkCell.css")
		Style style();
	}

	public static final Template TEMPLATE = GWT.create(Template.class);
	public static final Resources RESOURCES = GWT.create(Resources.class);

	static {
		RESOURCES.style().ensureInjected();
	}

	private boolean multilineStyle;
	private final String caption;

	public LinkCell(String caption) {
		super(BrowserEvents.CLICK, BrowserEvents.KEYDOWN);
		this.caption = caption;
	}

	@Override
	public void render(Context context, StringPair value, SafeHtmlBuilder sb) {
		if (value != null) {
			if (value.getRight() != null) {
				// Right part of the StringPair contains URL
				String className;
				if (multilineStyle) {
					className = RESOURCES.style().bLinkCell__multiline_text();
				} else {
					className = RESOURCES.style().bLinkCell__text();
				}
				SafeUri url = UriUtils.fromSafeConstant(value.getRight());
				// Left part of the StringPair might contain cell's caption.
				String name = value.getLeft();
				if (name == null || name.trim().isEmpty()) {
					// In case the cell's caption is not specified in the left part of the StringPair take caption.
					name = caption;
				}
				sb.append(TEMPLATE.div(className, TEMPLATE.link(url, name)));
			}
		}
	}

	@Override
	protected void onEnterKeyDown(Context context, Element parent, StringPair value, NativeEvent event, ValueUpdater<StringPair> stringValueUpdater) {
		event.preventDefault();
		Element el = parent;
		while (el.hasChildNodes()) {
			el = el.getFirstChildElement();
			if (el.getTagName().equalsIgnoreCase("a")) {
				Window.Location.assign(AnchorElement.as(el).getHref());
				return;
			}
		}
	}

	public boolean isMultilineStyle() {
		return multilineStyle;
	}

	public void setMultilineStyle(boolean multilineStyle) {
		this.multilineStyle = multilineStyle;
	}

}
